﻿
Imports xmlctrl
Imports xhtmlctrl
Imports rssctrl
Imports webctrl

Public Class timenow
    Inherits cacheControlProcessor

    Public Const _pathidentity As String = "/time"
    Public Const formatQuery As String = "format"
    Public Const timezoneQuery As String = "timezone"

    Public Class formatSelection
        Public Const xml As String = "xml"
        Public Const xmlsep As String = "xmlsep"
        Public Const rss As String = "rss"
        Public Const rsssep As String = "rsssep"
    End Class

    Public Class tagname
        Public Const time As String = "time"
        Public Const [long] As String = "long"
        Public Const [short] As String = "short"
        Public Const timezone As String = "timezone"
        Public Const year As String = "year"
        Public Const month As String = "month"
        Public Const [date] As String = "date"
        Public Const day As String = "day"
        Public Const hour As String = "hour"
        Public Const minute As String = "minute"
        Public Const second As String = "second"
    End Class

    Public Overrides Function pathidentity() As String
        Return _pathidentity
    End Function

    Protected Overrides Function normalRetiredTicks() As Long
        'retired each second, though seems not necessary, avoid to create new page in 1 second
        Return secondsToTicks(1)
    End Function

    Private Function processXml(ByVal context As httpContext, ByVal timezone As Int64, _
                                ByRef control As xmlcontrol) As Boolean
        assert(Not context Is Nothing, "context is nothing.")

        Dim page As xmlpage = Nothing
        page = context.createControl(New xmlpage())

        Dim time As xmlcontrol = Nothing
        time = context.createControl(New xmlcontrol(tag:=tagname.time))
        page.addchild(time)

        Dim e As xmlcontrol = Nothing
        e = context.createControl(New xmlcontrol(tag:=tagname.timezone))
        e.text = timezone
        time.addchild(e)

        Dim longform As xmlcontrol = Nothing
        longform = context.createControl(New xmlcontrol(tag:=tagname.long))
        longform.text = longTime(timezone)
        time.addchild(longform)

        Dim shortform As xmlcontrol = Nothing
        shortform = context.createControl(New xmlcontrol(tag:=tagname.short))
        shortform.text = shortTime(timezone:=timezone)
        time.addchild(shortform)

        control = page
        Return True
    End Function

    Private Function processXmlsep(ByVal context As httpContext, ByVal timezone As Int64, _
                                   ByRef control As xmlcontrol) As Boolean
        assert(Not context Is Nothing, "context is nothing.")

        Dim page As xmlpage = Nothing
        page = context.createControl(New xmlpage())

        Dim time As xmlcontrol = Nothing
        time = context.createControl(New xmlcontrol(tag:=tagname.time))
        page.addchild(time)

        Dim d As Date = Nothing
        d = getTimezoneDate(timezone)

        Dim e As xmlcontrol = Nothing
        e = context.createControl(New xmlcontrol(tag:=tagname.timezone))
        e.text = timezone
        time.addchild(e)

        e = context.createControl(New xmlcontrol(tag:=tagname.year))
        e.text = d.Year
        time.addchild(e)

        e = context.createControl(New xmlcontrol(tag:=tagname.month))
        e.text = d.Month
        time.addchild(e)

        e = context.createControl(New xmlcontrol(tag:=tagname.date))
        e.text = d.Day
        time.addchild(e)

        e = context.createControl(New xmlcontrol(tag:=tagname.day))
        e.text = Convert.ToInt64(d.DayOfWeek)
        time.addchild(e)

        e = context.createControl(New xmlcontrol(tag:=tagname.hour))
        e.text = d.Hour
        time.addchild(e)

        e = context.createControl(New xmlcontrol(tag:=tagname.minute))
        e.text = d.Minute
        time.addchild(e)

        e = context.createControl(New xmlcontrol(tag:=tagname.second))
        e.text = d.Second
        time.addchild(e)

        control = page
        Return True
    End Function

    Private Function generateRssItem(ByVal context As httpContext, ByVal name As String, ByVal value As Object) As item
        assert(Not context Is Nothing, "context is nothing.")

        Dim rtn As item = Nothing
        rtn = context.createControl(New item())

        Dim title As rssctrl.title = Nothing
        title = context.createControl(New rssctrl.title())
        title.text = name
        rtn.addchild(title)

        Dim description As description = Nothing
        description = context.createControl(New description())
        description.text = value
        rtn.addchild(description)

        Return rtn
    End Function

    Private Function generateRsspage(ByVal context As httpContext) As rsspage
        assert(Not context Is Nothing, "context is nothing.")
        Dim page As rsspage = Nothing
        page = context.createControl(New rsspage())
        page.title().text = "timenow - " + applicationSign()

        Return page
    End Function

    Private Function processRss(ByVal context As httpContext, ByVal timezone As Int64, _
                                ByRef control As xmlcontrol) As Boolean
        assert(Not context Is Nothing, "context is nothing.")

        Dim page As rsspage = Nothing
        page = generateRsspage(context)

        page.channel().addchild(generateRssItem(context, tagname.timezone, timezone))
        page.channel().addchild(generateRssItem(context, tagname.long, longTime(timezone)))
        page.channel().addchild(generateRssItem(context, tagname.short, shortTime(timezone)))

        control = page
        Return True
    End Function

    Private Function processRsssep(ByVal context As httpContext, ByVal timezone As Int64, _
                                   ByRef control As xmlcontrol) As Boolean
        assert(Not context Is Nothing, "context is nothing.")

        Dim page As rsspage = Nothing
        page = generateRsspage(context)

        page.channel().addchild(generateRssItem(context, tagname.timezone, timezone))

        Dim d As Date = Nothing
        d = getTimezoneDate(timezone)
        With page.channel()
            .addchild(generateRssItem(context, tagname.year, d.Year))
            .addchild(generateRssItem(context, tagname.month, d.Month))
            .addchild(generateRssItem(context, tagname.date, d.Day))
            .addchild(generateRssItem(context, tagname.day, Convert.ToInt64(d.DayOfWeek)))
            .addchild(generateRssItem(context, tagname.hour, d.Hour))
            .addchild(generateRssItem(context, tagname.minute, d.Minute))
            .addchild(generateRssItem(context, tagname.second, d.Second))
        End With

        control = page
        Return True
    End Function

    Private Function processHtml(ByVal context As httpContext, ByVal timezone As Int64, _
                                 ByRef control As xmlcontrol) As Boolean
        assert(Not context Is Nothing, "context is nothing.")

        Dim page As xhtmlpage = Nothing
        page = context.createControl(New xhtmlpage())
        page.title().text = "timenow - " + applicationSign()
        page.body().style = "background:" + Convert.ToString(color.windowframe) + ";"

        Const servertimeId As String = "id_s"
        Const usertimeId As String = "id_u"
        timerun.invoke(page.inlineScript(), "'" + servertimeId + "'", False)
        timerun.invoke(page.inlineScript(), "'" + usertimeId + "'", True)

        Dim ul As ul = Nothing
        ul = context.createControl(New ul())
        page.body().addchild(ul)

        Dim li As li = Nothing
        li = context.createControl(New colorli(page.inlineScript()))
        ul.addchild(li)

        Dim xmltext As xmltext = Nothing
        xmltext = context.createControl(New xmltext())
        xmltext.text = "time from server is "
        li.addchild(xmltext)

        Dim label As label = Nothing
        label = context.createControl(New label())
        label.id = servertimeId
        label.text = "PENDING..."
        li.addchild(label)

        li = context.createControl(New colorli(page.inlineScript()))
        ul.addchild(li)

        xmltext = context.createControl(New xmltext())
        xmltext.text = "time from your machine is "
        li.addchild(xmltext)

        label = context.createControl(New label())
        label.id = usertimeId
        label.text = "PENDING..."
        li.addchild(label)

        li = context.createControl(New colorli(page.inlineScript()))
        ul.addchild(li)

        xmltext = context.createControl(New xmltext())
        xmltext.text = "the timezone you have provided is " + Convert.ToString(timezone) + ". [based on minute]"
        li.addchild(xmltext)

        li = context.createControl(New colorli(page.inlineScript()))
        ul.addchild(li)

        xmltext = context.createControl(New xmltext())
        xmltext.text = "time in the timezone you have provided when server responses is "
        li.addchild(xmltext)

        label = context.createControl(New label())
        label.text = longTime(timezone)
        li.addchild(label)

        li = context.createControl(New colorli(page.inlineScript()))
        ul.addchild(li)

        xmltext = context.createControl(New xmltext())
        xmltext.text = "other formats"
        li.addchild(xmltext)
        li.addchild(context.createControl(New br()))

        Dim a As a = Nothing
        a = context.createControl(New a())
        a.text = "xml format"
        a.href = urlUtils.appendQuery(strmid(pathidentity(), strlen(network.pathSeperator)), _
                                      formatQuery, formatSelection.xml, timezoneQuery, Convert.ToString(timezone))
        li.addchild(a)
        li.addchild(context.createControl(New br()))

        a = context.createControl(New a())
        a.text = "xml separate format"
        a.href = urlUtils.appendQuery(strmid(pathidentity(), strlen(network.pathSeperator)), _
                                      formatQuery, formatSelection.xmlsep, timezoneQuery, Convert.ToString(timezone))
        li.addchild(a)
        li.addchild(context.createControl(New br()))

        a = context.createControl(New a())
        a.text = "rss format"
        a.href = urlUtils.appendQuery(strmid(pathidentity(), strlen(network.pathSeperator)), _
                                      formatQuery, formatSelection.rss, timezoneQuery, Convert.ToString(timezone))
        li.addchild(a)
        li.addchild(context.createControl(New br()))

        a = context.createControl(New a())
        a.text = "rss separate format"
        a.href = urlUtils.appendQuery(strmid(pathidentity(), strlen(network.pathSeperator)), _
                                      formatQuery, formatSelection.rsssep, timezoneQuery, Convert.ToString(timezone))
        li.addchild(a)
        li.addchild(context.createControl(New br()))

        control = page
        Return True
    End Function

    Protected Overrides Function processImpl(ByVal context As httpContext, ByRef control As xmlcontrol) As Boolean
        assert(Not context Is Nothing, "context is nothing.")

        Dim format As String = Nothing
        format = context.url().query(formatQuery)
        Dim timezoneStr As String = Nothing
        timezoneStr = context.url().query(timezoneQuery)
        Dim timezone As Double
        If isemptystring(timezoneStr) OrElse Not convertor.todouble(timezoneStr, timezone) Then
            'if not timezone defined in url or the timezone is invalid, use UTC time
            timezone = 0
        Else
            'time.vb accept minutes as timezone
            If timezone <= 12 AndAlso timezone >= -12 Then
                'user input is a [-12,12] timezone
                timezone *= 60
            End If
            'otherwise, think it's a minute based timezone
        End If

        If strsame(format, formatSelection.xml, False) Then
            Return processXml(context, timezone, control)
        ElseIf strsame(format, formatSelection.xmlsep, False) Then
            Return processXmlsep(context, timezone, control)
        ElseIf strsame(format, formatSelection.rss, False) Then
            Return processRss(context, timezone, control)
        ElseIf strsame(format, formatSelection.rsssep, False) Then
            Return processRsssep(context, timezone, control)
        Else
            Return processHtml(context, timezone, control)
        End If

        Return True
    End Function
End Class

Public Class timenow2
    Inherits timenow

    Public Shadows Const _pathidentity As String = "/timenow"

    Public Overrides Function pathidentity() As String
        Return _pathidentity
    End Function
End Class

Public Class timerun
    Public Const functionName As String = "timerun"
    Public Const dateObjectName As String = "d"

    Public Shared Sub invoke(ByVal inlineScript As inlineScript, ByVal id As String, ByVal useUsertime As Boolean)
        assert(Not inlineScript Is Nothing, "inlineScript is nothing.")

        'base function to update time display
        inlineScript.addscript(functionName, "function " + functionName + "(d,i){" + _
                               "d.setSeconds(d.getSeconds()+1);" + _
                               changeInnerHtmlById.invoke(inlineScript, "i", "d.toString()") + ";}")

        Dim dateObjectName As String = Nothing
        copy(dateObjectName, timerun.dateObjectName)
        If useUsertime Then
            dateObjectName += "u"
        End If
        Dim share As String = Nothing
        webctrl.var.invoke(dateObjectName, "new Date()", share)
        strrplc(id, "'", "\'")
        strrplc(id, """", "\""")
        share += ";setInterval(""" + functionName + "(" + dateObjectName + "," + id + ")"",1000);"
        If Not useUsertime Then
            inlineScript.addscript("initialtimerun", share + dateObjectName + ".setTime(" + _
                                   Convert.ToString(getTimezoneDate(0).Subtract( _
                                       New Date(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds) + _
                                   ");")
        Else
            inlineScript.addscript("initialtimerun_u", share)
        End If
    End Sub
End Class